using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;

namespace XDLPipeline
{
    class BlenderCoordsProcessorHelper
    {        
        public static void NormalizePositions(XmlDocument xd, ContentProcessorContext context)
        {
            // nothing to do
        }

        static void NormalizeHull(XmlNode hullNode, ContentProcessorContext context)
        {
            XmlAttribute nameAttribute = hullNode.Attributes["name"];
            if (nameAttribute == null)
                throw new InvalidContentException("Invalid hull definition: missing 'name' attribute");

            foreach (XmlNode planeNode in hullNode.SelectNodes("Plane"))
            {
                XmlAttribute normalAttribute = planeNode.Attributes["normal"];
                if (normalAttribute == null)
                    throw new InvalidContentException("Invalid plane definition: missing 'normal' attribute");
                XmlAttribute pointAttribute = planeNode.Attributes["point"];
                if (pointAttribute == null)
                    throw new InvalidContentException("Invalid plane definition: missing 'point' attribute");

                Vector3 normal = XmlHelper.ReadXmlVector<Vector3>(normalAttribute.Value);
                Vector3 point = XmlHelper.ReadXmlVector<Vector3>(pointAttribute.Value);

                // make sure all hull vertices are within the negative half-space
                /*
                foreach (XmlNode vertexNode in hullNode.SelectNodes("Vertex"))
                {
                    XmlAttribute vertexPosAttribute = vertexNode.Attributes["position"];
                    if (vertexPosAttribute == null)
                        throw new InvalidContentException("Invalid hull vertex definition: missing 'position' attribute");

                    Vector3 p = XmlHelper.ReadXmlVector<Vector3>(vertexPosAttribute.Value);
                    // make sure every hull vertices are "behind" the hull planes
                    // make sure to avoid rounding error
                    // float are exported with a 3 digits precision
                    // comparison is safe with a 2 digits precision
                    float dot = (float)Math.Round(
                                    (double)Vector3.Dot(normal, p - point),
                                    2);
                    // context.Logger.LogImportantMessage("{0} vs. {1} = {2}", normal, p - point, dot);
                    if (dot > 0)
                        throw new InvalidContentException(
                            string.Format("Non-convex hull detected ({0}, {2}), outside point: {1}", nameAttribute.Value, p, dot));
                }
                */
                // normalize hull plane (once validated)

                // update the xml document (in place)
                normalAttribute.Value = XmlHelper.WriteXmlVector(normal);
                pointAttribute.Value = XmlHelper.WriteXmlVector(point);

            }
        }

        public static void NormalizeHulls(XmlDocument xd, ContentProcessorContext context)
        {
            // normalize plane orientations
            foreach (XmlNode hullNode in xd.SelectNodes("//Hull"))
            {
                NormalizeHull(hullNode, context);
            }
        }
    }
}
